package com.pie4cloud.pie.dmz.service;

import com.pie4cloud.pie.common.core.util.R;
import com.pie4cloud.pie.dmz.dto.SystemInfoDto;
import com.sun.management.OperatingSystemMXBean;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SystemMonitorService {

	public R<SystemInfoDto> getSystemInfo(){
		SystemInfoDto systemInfoDto=new SystemInfoDto();
		SystemInfo systemInfo =new SystemInfo();
		try {
			this.getCpuInfo(systemInfo,systemInfoDto);
			this.getMemoryInfo(systemInfoDto);
			this.getDiskInfo(systemInfo,systemInfoDto);
			if(systemInfoDto.getDiskUsage().doubleValue()>0.9||systemInfoDto.getCpuUsage().doubleValue()>0.9||systemInfoDto.getMemoryUsage().doubleValue()>0.9){
				systemInfoDto.setIsUsable(1);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
			return R.failed();
		}
		return R.ok(systemInfoDto);
	}

	private void getCpuInfo(SystemInfo systemInfo, SystemInfoDto systemInfoDto) throws InterruptedException {
		CentralProcessor processor = systemInfo.getHardware().getProcessor();
		long[] prevTicks = processor.getSystemCpuLoadTicks();
		// 睡眠1s
		TimeUnit.SECONDS.sleep(1);
		long[] ticks = processor.getSystemCpuLoadTicks();
		long nice = ticks[CentralProcessor.TickType.NICE.getIndex()]
				- prevTicks[CentralProcessor.TickType.NICE.getIndex()];
		long irq = ticks[CentralProcessor.TickType.IRQ.getIndex()]
				- prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
		long softirq = ticks[CentralProcessor.TickType.SOFTIRQ.getIndex()]
				- prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
		long steal = ticks[CentralProcessor.TickType.STEAL.getIndex()]
				- prevTicks[CentralProcessor.TickType.STEAL.getIndex()];
		long cSys = ticks[CentralProcessor.TickType.SYSTEM.getIndex()]
				- prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
		long user = ticks[CentralProcessor.TickType.USER.getIndex()]
				- prevTicks[CentralProcessor.TickType.USER.getIndex()];
		long iowait = ticks[CentralProcessor.TickType.IOWAIT.getIndex()]
				- prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
		long idle = ticks[CentralProcessor.TickType.IDLE.getIndex()]
				- prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
		long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
		BigDecimal s=new BigDecimal(idle).divide(new BigDecimal(totalCpu),4,BigDecimal.ROUND_HALF_UP);
		systemInfoDto.setCpuUsage(new BigDecimal(1).subtract(s));

	}
	private void getMemoryInfo(SystemInfoDto systemInfoDto) {
		OperatingSystemMXBean osmxb = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
		MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
		MemoryUsage memoryUsage = memoryMXBean.getHeapMemoryUsage();

		// 初始的总内存
		long initTotalMemorySize = memoryUsage.getInit();
		// 最大可用内存
		long maxMemorySize = memoryUsage.getMax();
		// 已使用的内存
		long usedMemorySize = memoryUsage.getUsed();
		// 总的物理内存
		String totalMemorySize = new DecimalFormat("#.##")
				.format(osmxb.getTotalPhysicalMemorySize() / 1024.0 / 1024 / 1024);
		// 剩余的物理内存
		String freePhysicalMemorySize = new DecimalFormat("#.##")
				.format(osmxb.getFreePhysicalMemorySize() / 1024.0 / 1024 / 1024);
		systemInfoDto.setInitTotalMemorySize(new BigDecimal(totalMemorySize));
		systemInfoDto.setMaxMemorySize(new BigDecimal(freePhysicalMemorySize));
		BigDecimal s = systemInfoDto.getMaxMemorySize().divide(systemInfoDto.getInitTotalMemorySize(),4, BigDecimal.ROUND_HALF_UP);
		systemInfoDto.setMemoryUsage(new BigDecimal(1).subtract(s));
	}
	private void getDiskInfo(SystemInfo systemInfo,SystemInfoDto systemInfoDto) {
		OperatingSystem os = systemInfo.getOperatingSystem();
		FileSystem fileSystem=os.getFileSystem();
		OSFileStore[] fsArray = fileSystem.getFileStores();
		long atotal=0;
		long afree=0;
		for (OSFileStore fs : fsArray) {
			long usable = fs.getUsableSpace();
			long total = fs.getTotalSpace();
			atotal+=total;
			afree+=(usable);
		}
		String totalDisk=new DecimalFormat("#.##")
				.format(atotal/ 1024.0 / 1024 / 1024) ;
		String freeDisk=new DecimalFormat("#.##")
				.format(afree/ 1024.0 / 1024 / 1024) ;
		systemInfoDto.setTotalDisk(new BigDecimal(totalDisk));
		systemInfoDto.setFreeDisk(new BigDecimal(freeDisk));
		BigDecimal s=systemInfoDto.getFreeDisk().divide(systemInfoDto.getTotalDisk(),4, BigDecimal.ROUND_HALF_UP);

		systemInfoDto.setDiskUsage(new BigDecimal(1).subtract(s));

	}

}
